package com.rosiminc.pm.game;

/**
 * This class represents a PipesMania game's options.
 * 
 * @author Shymon
 * 
 * 
 */
public class PipesManiaOptions {

	private static final int DEFAULT_SIZE = 10;

	private int numRows;
	private int numCols;
	private int numFlip = 0;
	private int numBlock = 0;

	/**
	 * This constructor creates an Options instance with a specified game board
	 * size.
	 * 
	 * @param rows
	 *            The number of rows
	 * @param cols
	 *            The number of columns
	 * @throws IllegalArgumentException
	 *             if number of rows or columns is smaller than 1
	 */
	public PipesManiaOptions(int rows, int cols) {
		setNumRows(rows);
		setNumCols(cols);
	}

	/**
	 * This constructor creates options with default size values.
	 */
	public PipesManiaOptions() {
		this(DEFAULT_SIZE, DEFAULT_SIZE);
	}

	/**
	 * This method returns the number of rows allowed by this option.
	 * 
	 * @return the number of rows
	 */
	public int getNumRows() {
		return numRows;
	}

	/**
	 * This method sets the number of rows. If the number is less than the
	 * previous one, constraints will be cleared.
	 * 
	 * @param rows
	 *            the number of rows
	 * @throws IllegalArgumentException
	 *             if the number of rows is smaller than 1
	 */
	public void setNumRows(int rows) {
		if (rows < 1)
			throw new IllegalArgumentException(
					"Number of rows may not be smaller than 1");

		int oldNumRows = numRows;
		numRows = rows;

		if (rows < oldNumRows)
			clearConstraints();
	}

	/**
	 * This method clears the constraints other than number of rows and columns.
	 */
	private void clearConstraints() {
		numBlock = 0;
		numFlip = 0;
	}

	/**
	 * This method returns the number of columns allowed by this option.
	 * 
	 * @return the number of columns
	 */
	public int getNumCols() {
		return numCols;
	}

	/**
	 * This method sets the number of columns. If the number is less than the
	 * previous one, constraints will be cleared.
	 * 
	 * @param cols
	 *            the number of columns
	 * @throws IllegalArgumentException
	 *             if the number of columns is smaller than 1
	 */
	public void setNumCols(int cols) {
		if (cols < 1)
			throw new IllegalArgumentException(
					"Number of columnss may not be smaller than 1");

		int oldNumCols = numCols;
		numCols = cols;

		if (cols < oldNumCols)
			clearConstraints();
	}

	/**
	 * This method returns the number of flip tiles allowed by this option.
	 * 
	 * @return the number of flip tiles
	 */
	public int getNumFlip() {
		return numFlip;
	}

	/**
	 * This method sets the number of flip tiles allowed by this option.
	 * 
	 * @param numFlip
	 *            the number of flip tiles
	 */
	public void setNumFlip(int numFlip) {
		if (numFlip < 0)
			throw new IllegalArgumentException(
					"Impossible to set a negative amount");

		if ((numBlock + numFlip) > (numRows * numCols))
			throw new IllegalArgumentException("Supply surpassed");

		this.numFlip = numFlip;
	}

	/**
	 * This method returns the number of block tiles allowed by this option.
	 * 
	 * @return the number of block tiles
	 */
	public int getNumBlock() {
		return numBlock;
	}

	/**
	 * This method sets the number of block tiles allowed by this option.
	 * 
	 * @param numBlock
	 *            the number of block tiles
	 */
	public void setNumBlock(int numBlock) {
		if (numBlock < 0)
			throw new IllegalArgumentException(
					"Impossible to set a negative amount");

		if ((numBlock + numFlip) > (numRows * numCols))
			throw new IllegalArgumentException("Supply surpassed");

		this.numBlock = numBlock;
	}

	/**
	 * This method returns the number of rotate tiles allowed by this option.
	 * 
	 * @return the number of rotate tiles
	 */
	public int getNumRotate() {
		return (numRows * numCols) - (numBlock + numFlip);
	}
}
